﻿using System.Collections;
using DimensionsHelper.Common.Metadata.Script;

namespace DimensionsHelper.LanguageService.Syntax;

public class CategoricalLiteral : Literal<Categorical>, IReadOnlyList<CategoryLiteral>
{
    private readonly SyntaxList<CategoryLiteral> _categories;
    private readonly SyntaxToken? _leftCurlyToken;
    private readonly SyntaxToken? _rightCurlyToken;

    internal CategoricalLiteral(SyntaxNode? parent, SyntaxToken? leftCurlyToken, SyntaxToken? rightCurlyToken) :
        base(SyntaxKinds.Categorical, new Categorical(), parent)
    {
        _categories = new SyntaxList<CategoryLiteral>();
        SetChildNullableField(ref _leftCurlyToken, SyntaxToken.IsNullOrEmpty, leftCurlyToken);
        SetChildNullableField(ref _rightCurlyToken, SyntaxToken.IsNullOrEmpty, rightCurlyToken);
    }


    /// <summary>
    ///     默认的空分类列表。
    /// </summary>
    public static CategoricalLiteral Empty { get; } = new(null, null, null);


    /// <summary>
    ///     左花括号
    /// </summary>
    public SyntaxToken? LeftCurlyToken => _leftCurlyToken;


    /// <summary>
    ///     右花括号
    /// </summary>
    public SyntaxToken? RightCurlyToken => _rightCurlyToken;


    /// <summary>
    ///     包含的分类值个数
    /// </summary>
    public int Count => _categories.Count;


    public IEnumerator<CategoryLiteral> GetEnumerator()
    {
        return _categories.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }


    /// <summary>
    ///     获取指定索引的分类值，如果不存在，将返回null。
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    public CategoryLiteral this[int index] => _categories[index];


    /// <summary>
    ///     如果给定的分类常量是空列表，返回true。
    /// </summary>
    public static bool IsEmptyCategorical(CategoricalLiteral? literal)
    {
        return literal == null
               || literal.IsEmpty
               || ReferenceEquals(literal, Empty)
               || literal.Count == 0;
    }


    /// <summary>
    ///     添加一个分类常量表达式，允许重复添加
    /// </summary>
    public void AddCategory(CategoryLiteral category)
    {
        AddChildMemberToReadOnlyField(_categories, category);
        Value.Add(category.Value);
    }


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        Accept(visitor, LeftCurlyToken, RightCurlyToken);
        AcceptList(visitor, _categories);
    }
}


public static partial class NodeFactory
{
    public static CategoricalLiteral CreateCategoricalLiteral(SyntaxNode? parent, SyntaxToken? leftCurlyToken,
        SyntaxToken? rightCurlyToken, IEnumerable<CategoryLiteral> categories)
    {
        CategoricalLiteral cat = new(parent, leftCurlyToken, rightCurlyToken);

        foreach (CategoryLiteral val in categories)
        {
            cat.AddCategory(val);
        }

        return cat;
    }
}